// evalUtils.js
import LabelConfig from '@/js/models/LabelConfig';
import { newRectFObject, newPolyFObject } from '@/js/utils/FabricControls';
import { getPointsFromBBox, getPointsFromSegs, getPointsFromSeg, getPointsLT, getPointsRB, calculatePolygonBounds } from '@/js/utils/geomUtils';
import { getCanvasCoords } from '@/js/utils/imageUtils';

class EvalResultDet {
    constructor(result_type) {
        // 评估结果的类型；GT/DT
        this.metric = 'bbox';
        this.result_type = result_type;

        // 与之关联的GT/DT
        this.match_obj = null;

        // 底层的数据存储
        this.labels = [];
        this.labels_geom_rect = [];
        this.labels_geom_poly = [];

        // canvas相关绘制
        this.canvas = null;
        this.image = null;
    }

    // 在canvas中渲染结果
    bindCanvas(canvas, image) {
        this.canvas = canvas;
        this.image = image;

        // 加载labels中的bbox和segmentation的数据
        for (let i = 0; i < this.labels.length; i++) {
            let label = this.labels[i];
            if (!label) continue;
            if (label.annotation_type == 'FN' && this.result_type == 'dt') continue;
            if (label.annotation_type == 'FP' && this.result_type == 'gt') continue;
            let bbox = this.paintBBox(label);
            this.labels_geom_rect[label.id] = bbox;
            // let segs = this.paintSegmentation(label);
            // this.labels_geom_poly[label.id] = segs;
            // for (let j = 0; j < segs.length; j++) {
            //     this.canvas.add(segs[j]);
            // }
        }

        for (let i = 0; i < this.labels_geom_rect.length; i++) {
            let rect = this.labels_geom_rect[i];
            rect && this.canvas.add(rect);
        }

        this.canvas.requestRenderAll();
    }

    // 绘制bbox
    paintBBox(label) {
        // console.log(`paintBBox label = `, label);
        // console.log(`this.result_type = ${this.result_type}, paintBBox annotation_type = `, label.annotation_type);
        // 按照评估结果类型，获取bbox
        let bbox = null;
        if (this.result_type === 'dt' && label.dt_bbox) {
            bbox = JSON.parse(label.dt_bbox);
        }
        if (this.result_type === 'gt' && label.gt_bbox) {
            bbox = JSON.parse(label.gt_bbox);
        }
        // console.log(`dt_bbox = ${label.dt_bbox}, gt_bbox = ${label.gt_bbox}, paintBBox bbox = `, bbox);

        // 判断是否需要绘制
        if (bbox === null || bbox.length === 0 || !this.image) {
            return;
        }
        let annotation_type = label.annotation_type.toLowerCase();
        bbox[2] += bbox[0];
        bbox[3] += bbox[1];
        let points = getPointsFromBBox(bbox);
        points = getCanvasCoords(this.image, points);
        let pt_tl = getPointsLT(points);
        let pt_rb = getPointsRB(points);
        let config = LabelConfig.getConfig(`evaluation.${annotation_type}_rect_style`);
        let rect = newRectFObject(label.id, { left: pt_tl.x, top: pt_tl.y, width: pt_rb.x - pt_tl.x, height: pt_rb.y - pt_tl.y }, config);
        // this.registerObjectEvents(rect);
        return rect;
    }

    paintSegmentation(label) {
        // console.warn('paintSegmentation segs = ', label.data.segmentation);
        let points = getPointsFromSegs(label.data.segmentation);
        if (points.length == 0) {
            return [];
        }

        let geom_polys = [];
        for (let i = 0; i < label.data.segmentation.length; i++) {
            let seg = label.data.segmentation[i];
            points = getPointsFromSeg(seg);
            points = getCanvasCoords(this.image, points);
            if (points && points.length > 0) {
                let pt_tl = getPointsLT(points);
                let poly = newPolyFObject(label.id, i, { points: points, left: pt_tl.x, top: pt_tl.y }, LabelConfig.getConfig('displaySeg'));
                geom_polys.push(poly);
                this.registerObjectEvents(poly);
            }
        }
        return geom_polys;
    }
}

// 从评测结果解析出来可以前端渲染的数据结构
function convertImageEvalResult(eval_result, filter) {
    let filter_iou = filter && filter.iou_threshold ? filter.iou_threshold : 0.5;
    let filter_area = filter && filter.area ? filter.area : 'all';

    // 创建dt、gt的数据对象
    let eval_result_dt = {
        image_id: eval_result.img_id,
        image_url: eval_result.img_path,
        name: eval_result.img_name,
        eval_result: new EvalResultDet('dt')
    };
    let eval_result_gt = {
        image_id: eval_result.img_id,
        image_url: eval_result.img_path,
        name: eval_result.img_name,
        eval_result: new EvalResultDet('gt')
    };
    eval_result_dt.eval_result.match_obj = eval_result_gt.eval_result;
    eval_result_gt.eval_result.match_obj = eval_result_dt.eval_result;

    // 根据filter解析labels
    let labels = eval_result.eval_details.filter((item) => {
        return item.iou_threshold === filter_iou && item.area === filter_area;
    });
    eval_result_dt.eval_result.labels = labels;
    eval_result_gt.eval_result.labels = labels;

    return {
        dt: eval_result_dt,
        gt: eval_result_gt
    };
}

export { convertImageEvalResult };
